// use assistant_chat::request::chat_request;
use assistant_shell::request::{shell_batch_script_request, shell_request};
// use assistant_tts::request::sv2tts_request;
use model_graph_common::utils::write_to_file;
use model_graph_rrai::device::{device_query_robot_by_id, device_search_robot_by_ability, Robot};
use model_graph_types::{
    assistant::{
        ability::AssistantAbility,
        chat::{ChatMessage, ChatOptions, ChatProvider},
        shell::{
            BatchScriptRequestMessage, ShellRequestMessage, ShellRequestOptions,
            ShellResponseMessage,
        },
        tts::{TtsRequestMessage, TtsRequestOptions, TtsResponseMessage},
    },
    connector::{Connector, QueryOptions},
    modeling::Value,
    peer::{get_peer_id, get_token},
};
use std::{collections::HashMap, hash::Hash};

use generator_prompts::chat::prompts_by_template;

use crate::{get_system_connector, prompts::prompts_query_one_template};

pub async fn assistant_local_chat(
    messages: Vec<ChatMessage>,
    options: ChatOptions,
) -> anyhow::Result<Vec<ChatMessage>> {
    tracing::debug!("{:?}", options);

    let ability = AssistantAbility::Chat;

    // 提示词服务
    let request_message = if let Some(false) = &options.prompt_enhance {
        messages
    } else {
        let selector = HashMap::new();
        // 查找提示词模板
        let template = prompts_query_one_template(ability.clone(), selector).await?;
        tracing::debug!("查询到的提示词模板:{:?}", template);
        // 生成提示词
        let prompts_options = if let Some(extensions) = &options.extensions {
            extensions.clone()
        } else {
            HashMap::new()
        };
        let request_message = prompts_by_template(template, messages, prompts_options).await?;
        tracing::debug!("生成的请求提示词:{:?}", request_message);
        request_message
    };

    // 查询接口服务相关信息
    let provider = if let Some(provider) = &options.provider {
        provider.clone()
    } else {
        let category = String::from("");
        let provider = assistant_query_one_provider(ability.clone(), category.clone()).await?;
        tracing::debug!("查询到的服务:{:?}", provider);
        provider
    };

    // let response = chat_request(provider, request_message, options).await?;
    // tracing::debug!("返回的消息:{:?}", response);
    // 执行action

    // 组合返回信息
    // Ok(response)
    Err(anyhow::anyhow!(""))
}

// pub async fn assistant_local_tts(
//     request_message: TtsRequestMessage,
//     options: TtsRequestOptions,
// ) -> anyhow::Result<()> {
//     tracing::debug!("{:?}", options);

//     // 提示词服务
//     let ability = AssistantAbility::SV2TTS;
//     let selector = HashMap::new();
//     // 查找提示词模板
//     let template = prompts_query_one_template(ability.clone(), selector).await?;
//     tracing::debug!("查询到的提示词模板:{:?}", template);
//     // 生成提示词
//     let prompts_options = if let Some(extensions) = &options.extensions {
//         extensions.clone()
//     } else {
//         HashMap::new()
//     };
//     // 查询接口服务相关信息
//     let category = String::from("");
//     let provider = assistant_query_one_provider(ability.clone(), category.clone()).await?;
//     tracing::debug!("查询到的服务:{:?}", provider);

//     let response = sv2tts_request(provider, request_message, options).await?;
//     tracing::debug!("返回的消息:{:?}", response.audio.len());

//     Ok(())
// }

// pub async fn assistant_local_sv2tts(
//     request_message: TtsRequestMessage,
//     local_path: String,
//     options: TtsRequestOptions,
// ) -> anyhow::Result<()> {
//     tracing::debug!("{:?}", options);

//     // 提示词服务
//     let ability = AssistantAbility::SV2TTS;
//     // 查询接口服务相关信息
//     let category = String::from("");
//     tracing::debug!("开始查询:{:?}", ability);
//     let provider = assistant_query_one_provider(ability.clone(), category.clone()).await?;
//     tracing::debug!("查询到的服务:{:?}", provider);

//     let local_file = if let Some(local_file) = &options.local_file {
//         local_file.clone()
//     } else {
//         String::from("test.wav")
//     };
//     //保存文件
//     let response = sv2tts_request(provider, request_message, options).await?;
//     write_to_file(local_path.as_str(), local_file.as_str(), &response.audio)?;
//     tracing::debug!("返回的消息:{:?}", response.audio.len());
//     Ok(())
// }

pub async fn assistant_local_shell(
    request_message: ShellRequestMessage,
    options: ShellRequestOptions,
) -> anyhow::Result<ShellResponseMessage> {
    tracing::debug!("{:?}", options);
    // 查询接口服务相关信息
    let ability = AssistantAbility::SHELL;
    let category = String::from("");
    //
    let provider = if let Some(true) = options.remote {
        assistant_query_one_provider(ability.clone(), category.clone()).await?
    } else {
        //
        ChatProvider::new_with_peer(get_peer_id()?, String::new(), None, None)?
    };
    tracing::debug!("查询到的服务:{:?}", provider);

    let response = shell_request(provider, request_message, options).await?;
    tracing::debug!("返回的消息:{:?}", response.options);

    Ok(response)
}

pub async fn assistant_local_batch_script(
    request_message: BatchScriptRequestMessage,
    options: ShellRequestOptions,
) -> anyhow::Result<ShellResponseMessage> {
    tracing::debug!("{:?}", options);
    // 查询接口服务相关信息
    let ability = AssistantAbility::SHELL;
    let category = String::from("");
    let provider = if let Some(true) = options.remote {
        assistant_query_one_provider(ability.clone(), category.clone()).await?
    } else {
        //
        ChatProvider::new_with_peer(get_peer_id()?, String::new(), None, None)?
    };
    tracing::debug!("查询到的服务:{:?}", provider);

    let response = shell_batch_script_request(provider, request_message, options).await?;
    tracing::debug!("返回的消息:{:?}", response.options);

    Ok(response)
}

pub async fn assistant_query_providers(
    ability: AssistantAbility,
    category: String,
) -> anyhow::Result<Vec<ChatProvider>> {
    //获取connector
    let connector = get_system_connector().await?;

    let args: Vec<Value> = vec![Value::String(ability.clone().try_into()?)];

    let (_, rows) = connector
        .query(
            &String::from(
                "select category, assistant_nickname, assistant_peer_id, assistant_robot_id, is_local, options from assistant_provider where assistant_ability = $1",
            ),
            &args,
            QueryOptions {},
        )
        .await?;

    let mut providers: Vec<ChatProvider> = vec![];

    let token = get_token()?;
    let self_peer = get_peer_id()?;

    for row in rows {
        //每一个表
        match row {
            Value::Array(cols) => {
                let peer_id = cols.get(2).map_or(String::new(), |f| match f {
                    Value::String(v) => v.clone(),
                    _ => String::new(),
                });

                let robot_id = cols.get(3).map_or(String::new(), |f| match f {
                    Value::String(v) => v.clone(),
                    _ => String::new(),
                });

                // let is_local = cols.get(4).map_or(1, |f| match f {
                //     Value::String(v) => v.clone(),
                //     _ => 1,
                // });
                let robot = device_query_robot_by_id(
                    &token,
                    &peer_id,
                    robot_id
                        .parse::<u32>()
                        .map_err(|err| anyhow::anyhow!("robot_id不是合法的整数!{}", err))?,
                )
                .await?;

                // let url = String::from("http://localhost:8080/v1/chat/completions");
                // let url = String::from("http://192.168.92.189:8080/v1/chat/completions");

                providers.push(_robot_to_provider(&self_peer, &robot)?);
            }
            _ => {
                tracing::debug!("==");
            }
        }
    }
    //默认的
    if providers.len() == 0 {
        let token = get_token()?;
        //没有配置，从本用户、本节点进行选择
        let robots = device_search_robot_by_ability(&token, &self_peer, ability.clone()).await?;
        tracing::debug!("robots:{:?}", robots);
        _robots_to_providers(&robots)
    } else {
        Ok(providers)
    }
}

pub async fn assistant_query_one_provider(
    ability: AssistantAbility,
    category: String,
) -> anyhow::Result<ChatProvider> {
    //
    assistant_query_providers(ability, category)
        .await?
        .pop()
        .map_or(Err(anyhow::anyhow!("没有查询到数据")), |v| Ok(v))
}

fn _robots_to_providers(robots: &Vec<Robot>) -> anyhow::Result<Vec<ChatProvider>> {
    let self_peer = get_peer_id()?;
    let mut res = vec![];
    for robot in robots {
        res.push(_robot_to_provider(&self_peer, robot)?);
    }
    Ok(res)
}

fn _robot_to_provider(self_peer: &String, robot: &Robot) -> anyhow::Result<ChatProvider> {
    let peer_id = &robot.peer_id;
    let url = robot.url.clone();
    let token_key = robot.token_key.clone();
    let token_value = robot.token_value.clone();

    let options = if let Some(options_str) = &robot.options {
        if let Ok(ops) = serde_json::from_str::<HashMap<String, String>>(options_str.as_str()) {
            ops
        } else {
            HashMap::new()
        }
    } else {
        HashMap::new()
    };

    let mut provider = if self_peer == peer_id {
        //本地
        ChatProvider::new(url, token_key, token_value)
    } else {
        ChatProvider::new_with_peer(peer_id.clone(), url, token_key, token_value)
    }?;
    provider.options = options;

    Ok(provider)
}
